package com.nonagon.melladesk.service;

import com.nonagon.melladesk.utils.JwtUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author flitsneak
 * @ClassName
 * @date 2021/4/2 16:29
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class JwtAuthenticationService implements ReactiveAuthenticationManager {

    private final JwtUtil jwtUtil;

    @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
        //log.info("访问 reactiveAuthenticationManager");
        return Mono.just(authentication)
                .map(auth->jwtUtil.parseToken(auth.getCredentials().toString()))//解析传入的jwt，异常则打印。
                .log()
                .onErrorResume(e->{
                    log.error("验证token时发生错误，错误类型为：{}，错误信息为：{}",e.getClass(),e.getMessage());
                    return Mono.empty();
                })
                .map(claims -> new UsernamePasswordAuthenticationToken(
                        claims.getSubject(),null, Stream.of(
                                claims.get(jwtUtil.getAuthoritiesTag()))
                        .peek(info-> log.info("auth权限信息 {}",info))
                        .map(it->(List<Map<String,String>>)it)
                        .flatMap(it->it.stream()
                                .map(i->i.get("authority"))
                                .map(SimpleGrantedAuthority::new))
                                .collect(Collectors.toList()))
                );

    }
}
